package studio.raptor.databus.client;

import com.google.protobuf.InvalidProtocolBufferException;
import java.util.List;
import java.util.Objects;
import javax.jms.JMSException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import studio.raptor.databus.command.ActiveMQBytesMessage;
import studio.raptor.databus.command.ActiveMQMessage;
import studio.raptor.databus.command.ActiveMQObjectMessage;
import studio.raptor.databus.command.ActiveMQTextMessage;
import studio.raptor.databus.command.Event;
import studio.raptor.databus.command.EventBasicData;
import studio.raptor.databus.command.EventBusinessData;
import studio.raptor.databus.command.EventBusinessDataProvideType;
import studio.raptor.databus.command.EventBusinessDataType;
import studio.raptor.databus.command.EventMetaData;
import studio.raptor.databus.command.EventMetaDataBusinessType;
import studio.raptor.databus.command.EventProtoBuf;
import studio.raptor.databus.command.EventTransportType;

/**
 * Created on 2017/8/4  <br>
 *
 * @author koalton
 */
public class EventMessage {

  Logger logger = LoggerFactory.getLogger(EventMessage.class);

  private ActiveMQMessage activeMQMessage ;
  private EventTransportType eventTransportType ;

  private EventMessage(){}

  EventMessage(ActiveMQMessage activeMQMessage,EventTransportType eventTransportType){
    this.activeMQMessage = activeMQMessage;
    this.eventTransportType = eventTransportType ;
  }


  public Event getEvent() throws JMSException, InvalidProtocolBufferException {
    if(Objects.equals(null,activeMQMessage)){
      return null;
    }
    Event event = null;
    if( eventTransportType == EventTransportType.EVENT_TRANSPORT_TYPE_ORIGINAL ){
      //原始方式传输--使用JDK。
      ActiveMQObjectMessage objectMessage = (ActiveMQObjectMessage)activeMQMessage;
      event = objectMessage.getEvent();
    }else if( eventTransportType == EventTransportType.EVENT_TRANSPORT_TYPE_SERIALIZATION ){
      //使用序列化框架传输
      ActiveMQBytesMessage bytesMessage = (ActiveMQBytesMessage)activeMQMessage;
      event = this.transFromBuf(bytesMessage.getEvent());
    }else if( eventTransportType == EventTransportType.EVENT_TRANSPORT_TYPE_TEXT ){
      //使用文本协议传输
      ActiveMQTextMessage textMessage = (ActiveMQTextMessage)activeMQMessage;
      event = textMessage.getEvent();
    }else{
      logger.error(" EventTransportType is not sure ");
    }

    return event;
  }

  /**
   * 对消息进行ACK
   * @throws JMSException
   */
  public void acknowledge() throws JMSException {
    activeMQMessage.acknowledge();
  }

  /**
   * 将EventProtoBuf.Event转换为对外暴露的Event对象
   * <p>当使用序列化对象传输时，消费者模块使用</p>
   * @param event 序列化对象
   * @return 对外暴露的Event对象
   */
  protected static Event transFromBuf(EventProtoBuf.Event event){
    if( Objects.equals(null,event) ){
      return null ;
    }
    //转换基础数据
    EventBasicData basicData = new EventBasicData();
    basicData.setKindId(event.getEventBasicData().getKindId());
    basicData.setName(event.getEventBasicData().getName());
    basicData.setSource(event.getEventBasicData().getSource());
    basicData.setDeliverTime(event.getEventBasicData().getDeliverTime());

    //转换业务数据
    EventBusinessData businessData = new EventBusinessData();
    businessData.setContent(event.getEventBusinessData().getContent());
    businessData.setDataService(event.getEventBusinessData().getDataService());
    switch ( event.getEventBusinessData().getDataType() ){
      case DATATYPE_JSON:
        businessData.setDataType(EventBusinessDataType.DATATYPE_JSON);
        break;
      case DATATYPE_XML:
        businessData.setDataType(EventBusinessDataType.DATATYPE_XML);
        break;
      case DATATYPE_CUSTOM:
        businessData.setDataType(EventBusinessDataType.DATATYPE_CUSTOM);
        break;
      default:
        break;
    }
    switch ( event.getEventBusinessData().getProvideType() ){
      case PROVIDE_TYPE_CARRY:
        businessData.setProvideType(EventBusinessDataProvideType.PROVIDE_TYPE_CARRY);
        break;
      case PROVIDE_TYPE_SERVICE:
        businessData.setProvideType(EventBusinessDataProvideType.PROVIDE_TYPE_SERVICE);
        break;
      default:
        break;
    }

    //元数据转换
    EventMetaData metaData = new EventMetaData();
    metaData.setBusinessNo(event.getEventMetaData().getBusinessNo());
    metaData.setRegionId(event.getEventMetaData().getRegionId());
    switch ( event.getEventMetaData().getBusinessType() ){
      case BUSINESS_TYPE_NRM:
        metaData.setBusinessType(EventMetaDataBusinessType.BUSINESS_TYPE_NRM);
        break;
      case BUSINESS_TYPE_SAR:
        metaData.setBusinessType(EventMetaDataBusinessType.BUSINESS_TYPE_SAR);
        break;
      case BUSINESS_TYPE_OTH:
        metaData.setBusinessType(EventMetaDataBusinessType.BUSINESS_TYPE_OTH);
        break;
      default:
        break;
    }
    metaData.setProdIds(event.getEventMetaData().getProdIds());
    metaData.setOfferIds(event.getEventMetaData().getOfferIds());
    metaData.setOfferSpecAttrs(event.getEventMetaData().getOfferSpecAttrs());
    metaData.setServiceOfferIds(event.getEventMetaData().getServiceOfferIds());
    metaData.setServiceSpecAttrs(event.getEventMetaData().getServiceSpecAttrs());

    List<Long> offerProdId =  event.getEventMetaData().getOfferProdIdList();
    if( !Objects.equals(null,offerProdId) && offerProdId.size() >0){
      Long[] offerProdIdA = (Long[])offerProdId.toArray();
      metaData.setOfferProdId(offerProdIdA);
    }
    metaData.setOrderTypeIds(event.getEventMetaData().getOrderTypeIds());

    List<Long> custId =  event.getEventMetaData().getCustIdList();
    if( !Objects.equals(null,custId) && custId.size() >0){
      Long[] custIdA = (Long[])custId.toArray();
      metaData.setCustId(custIdA);
    }

    List<Long> acctId =  event.getEventMetaData().getAcctIdList();
    if( !Objects.equals(null,acctId) && acctId.size() >0){
      Long[] acctIdA = (Long[])acctId.toArray();
      metaData.setAcctId(acctIdA);
    }

    List<Long> prodInstId =  event.getEventMetaData().getProdInstIdList();
    if( !Objects.equals(null,prodInstId) && prodInstId.size() >0){
      Long[] prodInstIdA = (Long[])prodInstId.toArray();
      metaData.setProdInstId(prodInstIdA);
    }

    List<Long> offerInstId =  event.getEventMetaData().getOfferInstIdList();
    if( !Objects.equals(null,offerInstId) && offerInstId.size() >0){
      Long[] offerInstIdA = (Long[])offerInstId.toArray();
      metaData.setOfferInstId(offerInstIdA);
    }
    metaData.setPublicMap(event.getEventMetaData().getPublicMapMap());

    Event e = new Event(basicData,businessData,metaData);
    return e ;
  }

  /**
   * 将Event对象转为EventProtoBuf.Event 对象
   * <p>当使用序列化框架对消息对象进行传输时，生产者模块使用</p>
   * @param event Event事件对象
   * @return EventProtoBuf事件对象
   */
  protected static EventProtoBuf.Event transFromEvent(Event event){
    if( Objects.equals(null,event) ){
      return null ;
    }

    //转换基础数据
    EventProtoBuf.EventBasicData.Builder basicDataBuilder = EventProtoBuf.EventBasicData.newBuilder();
    basicDataBuilder.setName(event.getEventBasicData().getName());
    basicDataBuilder.setKindId(event.getEventBasicData().getKindId());
    basicDataBuilder.setSource(event.getEventBasicData().getSource());
    basicDataBuilder.setDeliverTime(event.getEventBasicData().getDeliverTime());
    EventProtoBuf.EventBasicData basicData = basicDataBuilder.build();

    //转换业务数据
    EventProtoBuf.EventBusinessData.Builder businessDataBuilder = EventProtoBuf.EventBusinessData.newBuilder();
    businessDataBuilder.setContent(event.getEventBusinessData().getContent());
    switch ( event.getEventBusinessData().getDataType() ){
      case DATATYPE_JSON:
        businessDataBuilder.setDataType(EventProtoBuf.EventBusinessDataType.DATATYPE_JSON);
        break;
      case DATATYPE_XML:
        businessDataBuilder.setDataType(EventProtoBuf.EventBusinessDataType.DATATYPE_XML);
        break;
      case DATATYPE_CUSTOM:
        businessDataBuilder.setDataType(EventProtoBuf.EventBusinessDataType.DATATYPE_CUSTOM);
        break;
      default:
        break;
    }
    switch ( event.getEventBusinessData().getProvideType() ){
      case PROVIDE_TYPE_CARRY:
        businessDataBuilder.setProvideType(EventProtoBuf.EventBusinessDataProvideType.PROVIDE_TYPE_CARRY);
        break;
      case PROVIDE_TYPE_SERVICE:
        businessDataBuilder.setProvideType(EventProtoBuf.EventBusinessDataProvideType.PROVIDE_TYPE_SERVICE);
        break;
      default:
        break;
    }
    businessDataBuilder.setDataService(event.getEventBusinessData().getDataService());
    EventProtoBuf.EventBusinessData businessData = businessDataBuilder.build();

    //转换元数据
    EventProtoBuf.EventMetaData.Builder metaDataBuilder = EventProtoBuf.EventMetaData.newBuilder();
    metaDataBuilder.setBusinessNo(event.getEventMetaData().getBusinessNo());
    metaDataBuilder.setRegionId(event.getEventMetaData().getRegionId());
    switch ( event.getEventMetaData().getBusinessType() ){
      case BUSINESS_TYPE_NRM:
        metaDataBuilder.setBusinessType(EventProtoBuf.EventMetaDataBusinessType.BUSINESS_TYPE_NRM);
        break;
      case BUSINESS_TYPE_SAR:
        metaDataBuilder.setBusinessType(EventProtoBuf.EventMetaDataBusinessType.BUSINESS_TYPE_SAR);
        break;
      case BUSINESS_TYPE_OTH:
        metaDataBuilder.setBusinessType(EventProtoBuf.EventMetaDataBusinessType.BUSINESS_TYPE_OTH);
        break;
      default:
        break;
    }
    if( !Objects.equals(null,event.getEventMetaData().getProdIds()) ){
      metaDataBuilder.setProdIds(event.getEventMetaData().getProdIds());
    }
    if( !Objects.equals(null,event.getEventMetaData().getOfferIds())){
      metaDataBuilder.setOfferIds(event.getEventMetaData().getOfferIds());
    }
    if( !Objects.equals(null,event.getEventMetaData().getOfferSpecAttrs()) ){
      metaDataBuilder.setOfferSpecAttrs(event.getEventMetaData().getOfferSpecAttrs());
    }
    if( !Objects.equals(null,event.getEventMetaData().getServiceOfferIds()) ){
      metaDataBuilder.setServiceOfferIds(event.getEventMetaData().getServiceOfferIds());
    }
    if( !Objects.equals(null,event.getEventMetaData().getServiceSpecAttrs())){
      metaDataBuilder.setServiceSpecAttrs(event.getEventMetaData().getServiceSpecAttrs());
    }
    Long[] offerProdId = event.getEventMetaData().getOfferProdId();
    if( offerProdId != null && offerProdId.length > 0 ){
      for (Long el : offerProdId) {
        metaDataBuilder.addOfferProdId(el);
      }
    }
    if(!Objects.equals(null,event.getEventMetaData().getOrderTypeIds())){
      metaDataBuilder.setOrderTypeIds(event.getEventMetaData().getOrderTypeIds());
    }
    Long[] custId = event.getEventMetaData().getCustId();
    if( custId != null && custId.length > 0 ){
      for (Long el : custId) {
        metaDataBuilder.addCustId(el);
      }
    }
    Long[] acctId = event.getEventMetaData().getAcctId();
    if( acctId != null && acctId.length > 0 ){
      for (Long el : acctId) {
        metaDataBuilder.addAcctId(el);
      }
    }
    Long[] prodInstId = event.getEventMetaData().getProdInstId();
    if( prodInstId != null && prodInstId.length > 0 ){
      for (Long el : prodInstId) {
        metaDataBuilder.addProdInstId(el);
      }
    }
    Long[] offerInstId = event.getEventMetaData().getOfferInstId();
    if( offerInstId != null && offerInstId.length > 0 ){
      for (Long el : offerInstId) {
        metaDataBuilder.addOfferInstId(el);
      }
    }
    metaDataBuilder.putAllPublicMap(event.getEventMetaData().getPublicMap());
    EventProtoBuf.EventMetaData eventMetaData = metaDataBuilder.build();

    EventProtoBuf.Event.Builder eventBuilder = EventProtoBuf.Event.newBuilder();
    eventBuilder.setEventBasicData(basicData);
    eventBuilder.setEventBusinessData(businessData);
    eventBuilder.setEventMetaData(eventMetaData);


    EventProtoBuf.Event eventProtoBuf = eventBuilder.build();
    return eventProtoBuf ;
  }



}
